import { FunctionalComponent } from "vue";
import echarts, { EChartsOption } from "./echarts";
import { debounce, merge } from "lodash-es";

interface Props {
  height?: number;
}

type UseChartsReturn = [
  FunctionalComponent<Props>,
  {
    setLoading: (showLoading: boolean) => void;
    setOptions: (options: EChartsOption) => void;
  }
];

export default function useCharts(options: EChartsOption): UseChartsReturn {
  let chart: Nullable<echarts.ECharts> = null;
  let chartOptions: EChartsOption = options;

  const setLoading = (showLoading: boolean) => {
    if (showLoading) chart?.showLoading();
    else chart?.hideLoading();
  };

  const setOptions = (options: EChartsOption) => {
    chartOptions = merge(options, chartOptions);
    chart?.setOption(options);
  };

  const CustomCharts = defineComponent<Props>({
    props: {
      height: {
        type: Number,
        default: 480,
      },
    },
    setup({ height }) {
      const chartsRef = ref<HTMLDivElement>();
      const { isDarkMode } = useTheme();

      const handleOnChartResize = debounce(() => {
        if (chart) chart.resize();
      }, 100);

      const init = () => {
        chart && chart.dispose();
        chart = echarts.init(chartsRef.value, isDarkMode.value ? "guat-dark" : "light");
        chartOptions && setOptions(chartOptions);
        window.removeEventListener("resize", handleOnChartResize);
        window.addEventListener("resize", handleOnChartResize);
      };

      watch(isDarkMode, init);

      onMounted(async () => {
        await nextTick();
        init();
      });

      onUnmounted(() => {
        window.removeEventListener("resize", handleOnChartResize);
        if (chart) chart.dispose();
      });

      return () => (
        <div
          class="w-full"
          style={{
            height: `${height}px`,
          }}
          ref={chartsRef}
        />
      );
    },
  });

  return [
    CustomCharts as any,
    {
      setLoading,
      setOptions,
    },
  ];
}
